"""
在数据分析中，经常会出现识别连续的需求，在本例中，我们不仅要找出连续相同的数，还需要在满足连续的位置处标记是第几个连续的，即连续情况的序号。
"""

import pandas as pd

l = [0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1]
df = pd.DataFrame(l, columns=["a"])
print(df)

"""
a 列由 0 和 1 组成，我们需要关注 1 的情况，
如果连续有 3 个 1 表示满足连续情况，
再将第几次连续标记在这组数据的最后一个位置。
"""

"""思路
总体思路是，
先得到一个 Series，索引为要标识的位置，值为序号值，
最后将这个 Series 添加成新列。
"""

# 先增加一列 b 作为辅助列，它的作用是对连续的数据进行分组，并填充组序号：
df = df.assign(b=df['a'].ne(df['a'].shift()).cumsum())
print(df)
"""

以上代码判断当前值是否与它的下一个值不相同，为真表示不连续，得到的是一个布尔序列，
累加方法 cumsum() 则对这个布尔序列计算，得到各连续组的序号。

它的下一个值：df['a'].shift()
判断是否相同：df['a'].ne(df['a'].shift())
得到各连续组的序号：df['a'].ne(df['a'].shift()).cumsum()
"""

# 由于要标记的是 1 的连续，接着筛选 a 列为 1 的数据：
df1 = df.loc[df["a"] == 1]
print(df1)

# 再按序号分组筛选出数据大于等于 3 的数据：
df2 = df1.groupby("b").filter(lambda x: x["b"].count() >= 3)
print(df2)

# 由于要标记在连续组的最后一个上，再按序号分组筛选出每组最后一个值：
df3 = df2.groupby('b').tail(1)
print(df3)

# 这时，我们即有要标识的位置信息（即索引标签值），
# 最后再利用 a 的值全为 1 特征，累加获得标识序号，并将它赋值给一个标识符：

ser = df3["a"].cumsum()
print(ser)

# 最后用 eval 添加一列：
df = df.eval("b=@ser")
# 将缺失值填充为空
df.fillna("", inplace=True)
print(df)
